﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Ymatou.ServiceCenter
{
    /// <summary>
    /// 服务依赖统计值采样
    /// </summary>
    public class ServiceDependencySampling
    {
        private readonly object _syncRoot = new object();
        /// <summary>
        /// 服务消费者的应用编号
        /// </summary>
        public string ConsumerAppId { get; set; }

        /// <summary>
        /// 接口名称
        /// </summary>
        public string ApiName { get; set; }

        /// <summary>
        /// 服务提供者的应用编号
        /// </summary>
        public string ProviderAppId { get; set; }

        /// <summary>
        /// 接口地址
        /// </summary>
        public string ApiPath { get; set; }

        /// <summary>
        /// 采样时间段开始时间
        /// </summary>
        public DateTime BeginTime { get; set; }

        /// <summary>
        /// 采样时间段结束时间
        /// </summary>
        public DateTime EndTime { get; set; }        

        /// <summary>
        /// 采样时间段为多少秒
        /// </summary>
        public double SamplingElapsedSeconds
        {
            get { return (EndTime - BeginTime).TotalSeconds; }
        }

        /// <summary>
        /// 采样时间段内总接口请求数
        /// </summary>
        public long TotalRequestTimes { get; set; }

        /// <summary>
        /// 采样时间段内总接口请求失败数
        /// </summary>
        public long TotalFailTimes { get; set; }

        /// <summary>
        /// 采样时间段内接口调用总耗时毫秒数
        /// </summary>
        public long TotalRequestElapsedMilliseconds { get; set; }

        /// <summary>
        /// 采样时间段内接口调用最大耗时毫秒数
        /// </summary>
        public long MaxElapsedTime { get; set; }

        /// <summary>
        /// 采样时间段内接口调用最小耗时毫秒数
        /// </summary>
        public long MinElapsedTime { get; set; }


        public void ChangeData(long requestElapsedMilliseconds, bool isFail)
        {
            lock (_syncRoot)
            {
                if (MinElapsedTime ==0 || MinElapsedTime > requestElapsedMilliseconds)
                    MinElapsedTime = requestElapsedMilliseconds;
                if (MaxElapsedTime == 0 || MaxElapsedTime < requestElapsedMilliseconds)
                    MaxElapsedTime = requestElapsedMilliseconds;

                this.TotalRequestTimes++;
                if (isFail)
                    this.TotalFailTimes++;
                this.TotalRequestElapsedMilliseconds += requestElapsedMilliseconds;
            }
        }

        public ServiceDependencySampling CloneAndReset()
        {
            lock (_syncRoot)
            {
                ServiceDependencySampling sampling = new ServiceDependencySampling
                {
                    ConsumerAppId = this.ConsumerAppId,
                    ApiName = this.ApiName,
                    ProviderAppId = this.ProviderAppId,                    
                    ApiPath = this.ApiPath,
                    BeginTime = this.BeginTime,
                    EndTime = DateTime.Now,
                    TotalRequestTimes = this.TotalRequestTimes,
                    TotalFailTimes = this.TotalFailTimes,
                    TotalRequestElapsedMilliseconds = this.TotalRequestElapsedMilliseconds,
                    MinElapsedTime = this.MinElapsedTime,
                    MaxElapsedTime = this.MaxElapsedTime
                };
                this.BeginTime = DateTime.Now;
                this.TotalRequestTimes = 0;
                this.TotalFailTimes = 0;
                this.TotalRequestElapsedMilliseconds = 0;
                this.MinElapsedTime = 0;
                this.MaxElapsedTime = 0;

                return sampling;
            }
        }

    }
}
